//
// ShaderEffect.h
//

#ifndef __SHADER_EFFECT_H__
#define __SHADER_EFFECT_H__

#include "SevenHeader.h"
#include "DebugFrame.h"

typedef D3DXHANDLE SHADER_VAR;

class CShaderEffect : public CDebugFrame
{
	friend class CGraphics;

public:
	INTERNAL_MEMORY_CHECK(SN_SHADER_EFFECT);

public:
	CShaderEffect(void);
	~CShaderEffect(void);

	bool load(CGraphics *pGraphics, void *pShader, size_t uLength);
	void unload(void);

	SHADER_VAR	getVariableHandle(const char *pszVariableName);
	UINT		getTextureRegister(SHADER_VAR hVariable);
	UINT		getTextureRegisterByName(const char *pszVariableName);

	template<typename T>
	void setVariableByName(CGraphics *pGraphics, const char *pszVariableName, const T &value)
	{
		setVariable<T>(pGraphics, getVariableHandle(pszVariableName), value);
	}

	template<typename T>
	void setVariable(CGraphics *pGraphics, SHADER_VAR hVariable, const T &value)
	{
		if(typeid(T) == typeid(float)) {
			_pConstant->SetFloat(
				pGraphics->getDeviceInterface(),
				hVariable,
				(float)value);
		}
		// More types to be added.
	}

private:
	union {
		LPDIRECT3DPIXELSHADER9 _pPixelShader;
		LPDIRECT3DVERTEXSHADER9 _pVertexShader;
	};

	enum ShaderType
	{
		ShaderType_Unloaded,
		ShaderType_PixelShader,
		ShaderType_VertexShader
	} _type;

	LPD3DXCONSTANTTABLE _pConstant;

private:
	CShaderEffect(const CShaderEffect &effect);
	CShaderEffect &operator=(const CShaderEffect &effect);
};

#endif // __SHADER_EFFECT_H__
